#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <linux/serial.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <termios.h>
#include <sys/select.h>
#include <stdint.h>

int open_port(const char *dev)
{
	int fd = open(dev, O_RDWR | O_NOCTTY | O_NDELAY);
	if (fd < 0) {
		perror("open port /dev/ttyS2\n");
		exit(-1);
	}

	struct serial_rs485 rs485conf;
	memset(&rs485conf, 0, sizeof(rs485conf));

	if (ioctl(fd, TIOCGRS485, &rs485conf) < 0) {
		perror("Error reading ioctl port");
	}

	rs485conf.padding[0] = 17;
	rs485conf.delay_rts_after_send = 2000;
	rs485conf.delay_rts_before_send = 2000;
	rs485conf.flags |= SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND;

	if (ioctl(fd, TIOCSRS485, &rs485conf) < 0) {
		perror("Error sending ioctl port");
	}

	/* Use read() and write() syscalls here... */

	if (ioctl(fd, TIOCGRS485, &rs485conf) < 0) {
		perror("Error reading ioctl port");
	}

	struct termios ts;
	tcgetattr(fd, &ts);
	cfmakeraw(&ts);
	cfsetspeed(&ts, B9600);
	ts.c_cflag |= PARENB;
	ts.c_cflag &= ~PARODD;
	ts.c_cflag &= ~CSTOPB;
	ts.c_cflag &= ~CSIZE;
	ts.c_cflag |= CS8;
	tcsetattr(fd, TCSANOW, &ts);

	return fd;
}

int read_port(int fd, uint8_t *buf, int length)
{
	int pos = 0, len = 0, ret = 0;
	fd_set rt, ort;
	FD_ZERO(&ort);
	FD_SET(fd, &ort);
	struct timeval tm, otm;
	otm.tv_sec = 0;
	otm.tv_usec = 1000 * 100;
	while (pos < length) {
		rt = ort;
		tm = otm;
		ret = select(fd + 1, &rt, NULL, NULL, &tm);
		if (ret == 0) {
			return pos;
		} else if (ret < 0) {
			return -1;
		}
		len = read(fd, buf + pos, length - pos);
		if (len < 0) {
			return -1;
		}
		pos += len;
		buf[pos] = 0;
	}
	return pos;
}

// int main(int argc, char **argv)
// {
// 	uint8_t buf[1024], checksum = 0;
// 	int len = 0;
// 	int fd = open_port("/dev/ttyS2");

// 	uint8_t cmd[] = "\x01\x50\xFF\xFF\xFF\xFF\x4D";
// 	for (int i = 0; i < 7; i++) {
// 		printf("%02x ", cmd[i]);
// 	}
// 	printf("\n");

// 	for (;;) {
// 		checksum = 0;
// 		write(fd, cmd, 7);
// 		len = read_port(fd, buf, sizeof(buf));
// 		for (int i = 0; i < len - 1; i++) {
// 			printf("%02x ", (uint8_t)buf[i]);
// 			checksum += (uint8_t)buf[i];
// 		}
// 		printf("\nread len:%d checksum:%02x\n", len, checksum);
// 	}

// 	close(fd);
// 	return 0;
// }